﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using School.Entities;
namespace School.Accounting
{
    public static class Finance_Disc
    {
        private static SchoolEntities db = new SchoolEntities();
        public static IEnumerable<ACC_Expense> getValidExpense(bool Enable)
        {
            return (from E in db.ACC_Expense where E.Enable_Discount == Enable select E);
        }
        public static IQueryable<LU_Jobs> GetJobs()
        {
            return (from j in db.LU_Jobs select j);
        }
        public static IQueryable<SD_ParentsSocialStatus> GetParentsSocialStatus()
        {
            return (from p in db.SD_ParentsSocialStatus select p);
        }
        public static long AddDiscount(string Name, string Dis_Code, byte Type, string Details)
        {
            try
            {
                ACC_Discount Dis = new ACC_Discount();
                Dis.Name = Name;
                Dis.Code = Dis_Code;
                Dis.Type = Type;
                Dis.Detail = Details;
                db.AddToACC_Discount(Dis);
                db.SaveChanges();
                long id = Dis.Id;
                return id;

            }
            catch (Exception)
            {
                long id = 0;
                return id;
            }

        }

        public static bool AddDiscount_FatherJob(byte Type, int Father_Job_Id, long Discount_Id, decimal Value)
        {
            try
            {
                ACC_Discount_Fahter_Job Dis = new ACC_Discount_Fahter_Job();
                Dis.Father_Job_Id = Father_Job_Id;
                Dis.Type = Type;
                Dis.Discount_Id = Discount_Id;
                Dis.Value = Value;
                db.AddToACC_Discount_Fahter_Job(Dis);
                db.SaveChanges();
                return true;
            }
            catch (Exception)
            {
                return false;
            }

        }
        public static bool AddDiscount_FatherStatu(byte Type, int Father_Status_Id, long Discount_Id, decimal Value)
        {
            try
            {
                ACC_Discount_Father_Status Dis = new ACC_Discount_Father_Status();
                Dis.Father_Status_Id = Father_Status_Id;
                Dis.Type = Type;
                Dis.Discount_Id = Discount_Id;
                Dis.Value = Value;
                db.AddToACC_Discount_Father_Status(Dis);
                db.SaveChanges();
                return true;
            }
            catch (Exception)
            {
                return false;
            }

        }
        public static bool AddDiscount_MotherJob(byte Type, int Mother_Job_Id, long Discount_Id, decimal Value)
        {
            try
            {
                ACC_Discount_Mother_Job Dis = new ACC_Discount_Mother_Job();
                Dis.Mother_Job_Id = Mother_Job_Id;
                Dis.Type = Type;
                Dis.Discount_Id = Discount_Id;
                Dis.Value = Value;
                db.AddToACC_Discount_Mother_Job(Dis);
                db.SaveChanges();
                return true;
            }
            catch (Exception)
            {
                return false;
            }

        }
        public static bool AddDiscount_MotherStatue(byte Type, int Mother_Status, long Discount_Id, decimal Value)
        {
            try
            {
                ACC_Discount_Mother_Status Dis = new ACC_Discount_Mother_Status();
                Dis.Mother_Status = Mother_Status;
                Dis.Type = Type;
                Dis.Discount_Id = Discount_Id;
                Dis.Value = Value;
                db.AddToACC_Discount_Mother_Status(Dis);
                db.SaveChanges();
                return true;
            }
            catch (Exception)
            {
                return false;
            }

        }
        public static bool AddDiscount_Brother(byte Type, int Brothers_Number, long Discount_Id, decimal Value)
        {
            try
            {
                ACC_Discount_Brothers Dis = new ACC_Discount_Brothers();
                Dis.Type = Type;
                Dis.Discount_Id = Discount_Id;
                Dis.Value = Value;
                Dis.Brothers_Number = Brothers_Number;
                db.AddToACC_Discount_Brothers(Dis);
                db.SaveChanges();
                return true;
            }
            catch (Exception)
            {
                return false;
            }

        }

        public static bool AddDiscount_Other(byte Type, long Discount_Id, decimal Value)
        {
            try
            {
                ACC_Discount_Others Dis = new ACC_Discount_Others();
                Dis.Type = Type;
                Dis.Discount_Id = Discount_Id;
                Dis.Value = Value;
                db.AddToACC_Discount_Others(Dis);
                db.SaveChanges();
                return true;
            }
            catch (Exception)
            {
                return false;
            }

        }

        public static bool AddDiscount_Order(byte Type, int Student_Order, long Discount_Id, decimal Value)
        {
            try
            {
                ACC_Discount_Student_Order Dis = new ACC_Discount_Student_Order();
                Dis.Type = Type;
                Dis.Discount_Id = Discount_Id;
                Dis.Value = Value;
                Dis.Student_Order = Student_Order;
                db.AddToACC_Discount_Student_Order(Dis);
                db.SaveChanges();
                return true;
            }
            catch (Exception)
            {
                return false;
            }

        }


        public static void AddDiscount_Expense(long Expense_Id, long Discount_Id)
        {
            try
            {
                ACC_Expense_Discount Dis = new ACC_Expense_Discount();
                Dis.Expense_Id = Expense_Id;
                Dis.Discount_Id = Discount_Id;
                Dis.Discount_Id = Discount_Id;
                db.AddToACC_Expense_Discount(Dis);
                db.SaveChanges();
            }
            catch (Exception)
            {

            }

        }

        public static void ApplyDiscountTo(long Discount_Id, string[] campuses, string[] certificates, string[] stages, string[] grades)
        {
            if (campuses != null)
            {
                foreach (string campus in campuses)
                {
                    db.AddToACC_Discount_Campus(new ACC_Discount_Campus() { Discount_Id = Discount_Id, Campus_Id = int.Parse(campus) });
                }
            }

            if (certificates != null)
            {
                foreach (string certificate in certificates)
                {
                    db.AddToACC_Discount_Certificate(new ACC_Discount_Certificate() { Discount_Id = Discount_Id, Certificate_Id = int.Parse(certificate) });
                }
            }

            if (stages != null)
            {
                foreach (string stage in stages)
                {
                    db.AddToACC_Discount_Stage(new ACC_Discount_Stage() { Discount_Id = Discount_Id, Stage_Id = int.Parse(stage) });
                }
            }

            if (grades != null)
            {
                foreach (string grade in grades)
                {
                    db.AddToACC_Discount_Grade(new ACC_Discount_Grade() { Discount_Id = Discount_Id, Grade_Id = int.Parse(grade) });
                }
            }

            db.SaveChanges();
        }
        public static IEnumerable<GrdObject> GetExdiscount()
        {
            var query = from d in db.ACC_Discount
                        select new GrdObject
                        {
                            DisId = d.Id,
                            DisName = d.Name,
                            DisCode = d.Code,
                            ExpId = db.ACC_Expense_Discount.Where(s => s.Discount_Id == d.Id).FirstOrDefault().ACC_Expense.ID,
                            ExpName = db.ACC_Expense_Discount.Where(s => s.Discount_Id == d.Id).FirstOrDefault().ACC_Expense.Name,
                            Type = d.Type

                        };
            return query;
        }

        public static IEnumerable<ACC_Discount> Disc()
        {
            return (from s in db.ACC_Discount select s);
        }
        public static IEnumerable<DiscountObjectM> GetDiscount(int expenses, IEnumerable<ACC_Discount> discounts, long father_job = 0, long father_status = 0, long mother_job = 0, long mother_status = 0, int brothers = 0, int order = 0)
        {

            if (expenses != 0)
            {
                var a = from y in db.ACC_Expense_Discount where y.Expense_Id == expenses select y.Discount_Id;
                discounts = from x in discounts where (from y in db.ACC_Expense_Discount where y.Expense_Id == expenses select y.Discount_Id).Contains(x.Id) select x;
            }

            var all = discounts.Distinct();

            List<DiscountObjectM> rows = new List<DiscountObjectM>();

            var n = all.Select(z => z.Id);

            if (father_job != 0)
            {
                var fj = from x in db.ACC_Discount_Fahter_Job where n.Contains(x.Discount_Id) select x;

                if (fj.Count() > 0)
                {
                    foreach (var d in fj)
                    {
                        rows.Add(new DiscountObjectM() { Name = d.ACC_Discount.Name, Id = d.Discount_Id, TypeIn = d.Type, Value = d.Value, Code = d.ACC_Discount.Code, Type = d.ACC_Discount.Type });
                    }
                }
            }

            if (mother_job != 0)
            {
                var mj = from x in db.ACC_Discount_Mother_Job where n.Contains(x.Discount_Id) select x;

                if (mj.Count() > 0)
                {
                    foreach (var d in mj)
                    {
                        rows.Add(new DiscountObjectM() { Name = d.ACC_Discount.Name, Id = d.Discount_Id, TypeIn = d.Type, Value = d.Value, Code = d.ACC_Discount.Code, Type = d.ACC_Discount.Type });
                    }
                }
            }

            if (father_status != 0)
            {
                var fs = from x in db.ACC_Discount_Father_Status where n.Contains(x.Discount_Id) select x;

                if (fs.Count() > 0)
                {
                    foreach (var d in fs)
                    {
                        rows.Add(new DiscountObjectM() { Name = d.ACC_Discount.Name, Id = d.Discount_Id, TypeIn = d.Type, Value = d.Value, Code = d.ACC_Discount.Code, Type = d.ACC_Discount.Type });
                    }
                }
            }

            if (mother_status != 0)
            {
                var ms = from x in db.ACC_Discount_Mother_Status where n.Contains(x.Discount_Id) select x;

                if (ms.Count() > 0)
                {
                    foreach (var d in ms)
                    {
                        rows.Add(new DiscountObjectM() { Name = d.ACC_Discount.Name, Id = d.Discount_Id, TypeIn = d.Type, Value = d.Value, Code = d.ACC_Discount.Code, Type = d.ACC_Discount.Type });
                    }
                }
            }

            if (brothers != 0)
            {
                var br = from x in db.ACC_Discount_Brothers where n.Contains(x.Discount_Id) select x;

                if (br.Count() > 0)
                {
                    foreach (var d in br)
                    {
                        rows.Add(new DiscountObjectM() { Name = d.ACC_Discount.Name, Id = d.Discount_Id, TypeIn = d.Type, Value = d.Value, Code = d.ACC_Discount.Code, Type = d.ACC_Discount.Type });
                    }
                }
            }

            if (order != 0)
            {
                var so = from x in db.ACC_Discount_Student_Order where n.Contains(x.Discount_Id) select x;

                if (so.Count() > 0)
                {
                    foreach (var d in so)
                    {
                        rows.Add(new DiscountObjectM() { Name = d.ACC_Discount.Name, Id = d.Discount_Id, TypeIn = d.Type, Value = d.Value, Code = d.ACC_Discount.Code, Type = d.ACC_Discount.Type });
                    }
                }
            }

            var ot = from x in db.ACC_Discount_Others where n.Contains(x.Discount_Id) select x;

            if (ot.Count() > 0)
                foreach (var d in ot)
                {
                    rows.Add(new DiscountObjectM() { Name = d.ACC_Discount.Name, Id = d.Discount_Id, TypeIn = d.Type, Value = d.Value, Code = d.ACC_Discount.Code, Type = d.ACC_Discount.Type });
                }

            return rows;
        }
        public static bool IsDis_IdinVoucher(long Ex_Id)
        {
            var id = from v in db.ACC_Voucher
                     where v.Expense_Id == Ex_Id
                     select v;
            if (id.Count() != 0)
                return true;
            else
                return false;
        }
        public static bool IsDis_IdcloseinVoucher(long Ex_Id)
        {
            var id = from v in db.ACC_Voucher
                     where v.Is_Closed == true
                     select v;
            if (id.Count() != 0)
                return true;
            else
                return false;
        }
        public static bool DeleteDis(int Id, byte type)
        {
            if (type != 0 && type != null)
            {
                if (type == 1)
                {
                    IEnumerable<ACC_Discount_Others> deletequery = (from b in db.ACC_Discount_Others
                                                                    where b.Discount_Id == Id
                                                                    select b);
                    try
                    {
                        foreach (ACC_Discount_Others item in deletequery)
                        {

                            db.DeleteObject(deletequery);
                        }
                        db.SaveChanges();
                        return true;
                    }
                    catch (Exception)
                    {
                        return false;
                    }
                }
                if (type == 2)
                {
                    IEnumerable<ACC_Discount_Fahter_Job> deletequery = (from b in db.ACC_Discount_Fahter_Job
                                                                        where b.Discount_Id == Id
                                                                        select b);
                    try
                    {
                        foreach (ACC_Discount_Fahter_Job item in deletequery.ToList())
                        {
                            var select = db.ACC_Discount_Fahter_Job.Where(s => s.Id == item.Id).First();
                            db.DeleteObject(select);

                        }
                        db.SaveChanges();
                        return true;
                    }

                    catch (Exception)
                    {
                        return false;
                    }
                }
                if (type == 3)
                {
                    IEnumerable<ACC_Discount_Mother_Job> deletequery = (from b in db.ACC_Discount_Mother_Job
                                                                        where b.Discount_Id == Id
                                                                        select b);
                    try
                    {
                        foreach (ACC_Discount_Mother_Job item in deletequery)
                        {
                            db.DeleteObject(deletequery);
                        }
                        db.SaveChanges();
                        return true;
                    }
                    catch (Exception)
                    {
                        return false;
                    }
                }
                if (type == 4)
                {
                    IEnumerable<ACC_Discount_Father_Status> deletequery = (from b in db.ACC_Discount_Father_Status
                                                                           where b.Discount_Id == Id
                                                                           select b);
                    try
                    {
                        foreach (ACC_Discount_Father_Status item in deletequery)
                        {
                            db.DeleteObject(deletequery);
                        }
                        db.SaveChanges();
                        return true;

                    }
                    catch (Exception)
                    {

                        return false;
                    }

                }
                if (type == 5)
                {
                    IEnumerable<ACC_Discount_Mother_Status> deletequery = (from b in db.ACC_Discount_Mother_Status
                                                                           where b.Discount_Id == Id
                                                                           select b);
                    try
                    {
                        foreach (ACC_Discount_Mother_Status item in deletequery)
                        {
                            db.DeleteObject(deletequery);

                        }
                        db.SaveChanges();
                        return true;

                    }
                    catch (Exception)
                    {

                        return false;
                    }

                }
                if (type == 6)
                {
                    IEnumerable<ACC_Discount_Brothers> deletequery = (from b in db.ACC_Discount_Brothers
                                                                      where b.Discount_Id == Id
                                                                      select b);
                    try
                    {
                        foreach (ACC_Discount_Brothers item in deletequery)
                        {
                            db.DeleteObject(deletequery);
                        }
                        db.SaveChanges();
                        return true;

                    }
                    catch (Exception)
                    {

                        return false;
                    }
                }
                if (type == 7)
                {
                    IEnumerable<ACC_Discount_Student_Order> deletequery = (from b in db.ACC_Discount_Student_Order
                                                                           where b.Discount_Id == Id
                                                                           select b);
                    try
                    {
                        foreach (ACC_Discount_Student_Order item in deletequery)
                        {
                            db.DeleteObject(deletequery);
                        }
                        db.SaveChanges();
                        return true;

                    }
                    catch (Exception)
                    {

                        return false;
                    }

                }
                var delete = (from b in db.ACC_Discount
                              where b.Id == Id
                              select b).Single();
                try
                {
                    db.DeleteObject(delete);
                    db.SaveChanges();
                    return true;

                }
                catch (Exception)
                {

                    return false;
                }

            }
            else
                return false;
        }
        public static IEnumerable<ACC_Expense_Discount> GetExbyDis_Id(int Dis_id)
        {

            var eid = from c in db.ACC_Expense_Discount.Where(a => a.Discount_Id == Dis_id) select c;
            return eid;
        }
    }
}



public class GrdObject
{
    public long DisId { get; set; }

    public string DisName { get; set; }

    public string DisCode { get; set; }

    public long? ExpId { get; set; }

    public string ExpName { get; set; }

    public byte Type { get; set; }
}
public class DiscountObjectM
{
    public string Code { set; get; }
    public string Name { set; get; }
    public long Id { set; get; }
    public byte Type { set; get; }
    public byte TypeIn { set; get; }
    public decimal Value { set; get; }
}




